package com.xjoyt.pay.share.dao.impl;

import java.util.ArrayList;
import java.util.List;

import javax.persistence.criteria.Predicate;

import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.data.jpa.domain.Specification;

import com.xjoyt.pay.abstracts.AbstractDao;
import com.xjoyt.pay.dto.PageParam;
import com.xjoyt.pay.dto.PageResult;
import com.xjoyt.pay.share.dao.BucketRepositoryCustom;
import com.xjoyt.pay.share.params.BucketPageParam;
import com.xjoyt.pay.share.po.Bucket;
import com.xjoyt.pay.share.repository.BucketRepository;

public class BucketRepositoryImpl extends AbstractDao implements BucketRepositoryCustom {

	@Autowired
	private BucketRepository repository;

	@Override
	public PageResult<Bucket> loadPage(PageParam<BucketPageParam> param) {
		Pageable pageable = getPageable(param);
		Specification<Bucket> spec = getSpecification(param.query);
		Page<Bucket> pageReuslt = repository.findAll(spec, pageable);
		return new PageResult<>(pageReuslt.getTotalElements(), pageReuslt.getContent());
	}

	private Specification<Bucket> getSpecification(BucketPageParam param) {
		Specification<Bucket> spec = (root, query, cb) -> {
			List<Predicate> list = new ArrayList<>();
			if (StringUtils.isNotBlank(param.query)) {
				for (String string : param.query.split(" ")) {
					if (StringUtils.isBlank(string))
						continue;
					String like = "%" + string + "%";
					list.add(cb.or(cb.like(root.get("endpoint"), like), cb.like(root.get("accessKey"), like),
							cb.like(root.get("secretKey"), like), cb.like(root.get("bucketName"), like)));
				}
			}

			if (param.enabled != null) {
				if (param.enabled)
					list.add(cb.equal(root.get("enabled"), param.enabled));
				else
					list.add(cb.or(cb.equal(root.get("enabled"), false), cb.isNull(root.get("enabled"))));
			}
			if (CollectionUtils.isNotEmpty(list))
				query.where(cb.and(list.toArray(new Predicate[list.size()])));

			return null;
		};
		return spec;
	}

	@Override
	public Bucket findOneByEndpointAndAccessKeyAndSecretKeyAndName(String endpoint, String accessKey, String secretKey,
			String name) {
		Page<Bucket> page = repository.findAllByEndpointAndAccessKeyAndSecretKeyAndName(endpoint, accessKey, secretKey,
				name, getFirstPageable());
		return page.hasContent() ? page.iterator().next() : null;
	}

	@Override
	public Bucket findOneByIdNotAndEndpointAndAccessKeyAndSecretKeyAndName(String id, String endpoint, String accessKey,
			String secretKey, String name) {
		Page<Bucket> page = repository.findAllByIdNotAndEndpointAndAccessKeyAndSecretKeyAndName(id, endpoint, accessKey,
				secretKey, name, getFirstPageable());
		return page.hasContent() ? page.iterator().next() : null;
	}

	@Override
	public Bucket findOneByEnabledTrueAndDefaultBucketTrue() {
		Page<Bucket> page = repository.findAllByEnabledTrueAndDefaultBucketTrue(getFirstPageable());
		return page.hasContent() ? page.iterator().next() : null;
	}

}
